home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / kgdb-4.5 / ds3100.md / gdb / RCS / mips_kgdb_remote.c,v < prev   
Encoding:
Text File  |  1992-11-09  |  45.2 KB  |  1,895 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    jhh:1.2; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     92.11.08.21.34.36;  author jhh;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     92.08.05.17.21.55;  author jhh;  state Exp;
  16. branches 1.1.1.1;
  17. next     ;
  18.  
  19. 1.1.1.1
  20. date     92.08.20.12.46.58;  author jhh;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.2
  30. log
  31. @looks like Matt made a few changes -- jhh
  32. @
  33. text
  34. @/* Memory-access and commands for inferior process, for GDB.
  35.    Copyright (C)  1988 Free Software Foundation, Inc.
  36.  
  37. GDB is distributed in the hope that it will be useful, but WITHOUT ANY
  38. WARRANTY.  No author or distributor accepts responsibility to anyone
  39. for the consequences of using it or for whether it serves any
  40. particular purpose or works at all, unless he says so in writing.
  41. Refer to the GDB General Public License for full details.
  42.  
  43. Everyone is granted permission to copy, modify and redistribute GDB,
  44. but only under the conditions described in the GDB General Public
  45. License.  A copy of this license is supposed to have been given to you
  46. along with GDB so you can know your rights and responsibilities.  It
  47. should be in a file named COPYING.  Among other things, the copyright
  48. notice and this notice must be preserved on all copies.
  49.  
  50. In other words, go ahead and share GDB, but don't try to stop
  51. anyone else from sharing it farther.  Help stamp out software hoarding!
  52. */
  53. /*#define MACH_NUM_GPRS 32
  54. #define MACH_NUM_FPRS 32*/
  55. #include <stdio.h>
  56. #include <sprite.h>
  57. #include <signal.h>
  58. #include <sys/types.h>
  59. #include <sys/file.h>
  60. #include <errno.h>
  61. /*#include <kernel/ds3100.md/machConst.h>*/
  62. #include <kernel/machTypes.h>
  63. #include <kernel/dbg.h>
  64. #include <kernel/procTypes.h>
  65.  
  66. #include "defs.h"
  67. #include <sys/param.h>
  68. #include "frame.h"
  69. #include "inferior.h"
  70. #include "value.h"
  71. #include "expression.h"
  72. /*#include "wait.h"*/
  73. #include <sys/wait.h>
  74. #include "sprite.h"
  75. #include "target.h"
  76.  
  77. /*
  78.  * The data cache is just an array of characters.
  79.  */
  80. static char *dataCache;
  81.  
  82. /*
  83.  * There is information about kept about each cache block.
  84.  */
  85. typedef    struct {
  86.     int        version;    /* Version number of this cache block. */
  87.     char    *realAddr;    /* Actual address of data stored in the block.*/
  88. } CacheInfo;
  89. static CacheInfo    *cacheInfo;
  90. static int    currentVersion = 1;
  91.  
  92. /*
  93.  * Useful macros
  94.  * ERROR_NO_ATTACHED_HOST - Remote an error and abort if no host is
  95.  *                currently attached.
  96.  * MARK_DISCONNECTED - Mark a host a disconnected and free up state.
  97.  */
  98.  
  99. #define ERROR_NO_ATTACHED_HOST \
  100.     if (!hostName) error("No machine attached.");
  101.  
  102. #define MARK_DISCONNECTED  {     \
  103.     initialized = 0;          \
  104.     inferior_pid = 0;        \
  105.     hostName = (char *) 0;     \
  106.     free(dataCache);      \
  107.     free(cacheInfo);      \
  108.     }
  109.  
  110. extern struct target_ops remote_ops;    /* Forward decl */
  111. int remote_debugging = 0;
  112.  
  113. /*
  114.  * Hostname of attached remote hosts.  Error otherwise.
  115.  */
  116.  
  117. char *hostName;
  118.  
  119. static    int    initialized = 0; /* Set to true when remote connection is
  120.                   * initialized. */
  121.  
  122. /*
  123.  * Table mapping kernel exceptions into Unix signals.  
  124.  */
  125.  
  126. struct sig_mapping_struct {
  127.     char     *sig_name;    /* Print string for signal. */
  128.     int     dbgSig;     /* Boolean - A signal used by the debugger. */
  129.     int     unixSignal;     /* Unix signal equalient. */
  130. } sig_mapping[] =  {
  131. /* 0 */ { "Interrupt pending", 0, SIGILL },
  132. /* 1 */ { "TLB modified fault", 0, SIGSEGV },
  133. /* 2 */ { "TLB miss on load or ifetch", 0, SIGSEGV },
  134. /* 3 */ { "TLB miss on a store", 0, SIGSEGV },
  135. /* 4 */ { "Address error on a load or ifetch", 0, SIGBUS },
  136. /* 5 */ { "Address error on a store", 0, SIGBUS },
  137. /* 6 */ { "Bus error on an ifetch", 0, SIGBUS },
  138. /* 7 */ { "Bus error on a load or store", 0, SIGBUS },
  139. /* 8 */ { "System call", 0, SIGSYS },
  140. /* 9 */ { "Breakpoint",  1, SIGTRAP },
  141. /* 10 */ { "Reserved Instruction", 0, SIGILL },
  142. /* 11 */ { "Coprocessor Unusable",  0, SIGILL },
  143. /* 12 */ { "Arithmetic overflow",  0, SIGILL },
  144. /* 13 */ { "UNKNOWN EXCEPTION", 0, SIGSEGV },
  145. };
  146.  
  147. #define    NUM_SIG_MAPS    (sizeof(sig_mapping)/sizeof(sig_mapping[0]))
  148.  
  149.  
  150.  
  151. #define    PBUFSIZ    1024
  152.  
  153. /* Maximum number of bytes to read/write at once.  The value here
  154.    is chosen to fill up a packet (the headers account for the 32).  */
  155. #define MAXBUFBYTES ((PBUFSIZ-32)/2)
  156.  
  157.  
  158. /*
  159.  *----------------------------------------------------------------------
  160.  *
  161.  * Regnum_to_index --
  162.  *
  163.  *    Function mapping a gdb register number into an index.
  164.  *
  165.  * Results:
  166.  *    Index to Mach_State structure when treated as an array on ints.
  167.  *
  168.  * Side effects:
  169.  *    None.
  170.  *
  171.  *----------------------------------------------------------------------
  172.  */
  173. static int 
  174. Regnum_to_index(r) 
  175.     int    r;
  176.   Mach_RegState bud;
  177. #define    O(f)    ((int)&(bud.f)/sizeof(int))
  178.   if (r < 32) return O(regs[r]);
  179.   if (r < PC_REGNUM) return  O(fpRegs[r-32]);
  180.   if (r == PC_REGNUM) return O(pc);
  181.   if (r == HI_REGNUM) return O(mfhi);
  182.   if (r == LO_REGNUM) return O(mflo);
  183.   if (r == FCRCS_REGNUM) return O(fpStatusReg);
  184.   return -1;
  185. #undef O
  186. };
  187. int lastPid = -1;    /* Process ID of process being examined. -1
  188.                  * means process causing trap. */
  189.  
  190. /*
  191.  * The following variables are sued when using the core memory interface
  192.  * rather than active ethernet debugging.
  193.  */
  194. static int remoteCoreChan = -1;    /* Open file descriptor of core file. -1 
  195.                  * means no file open. */
  196. static char *remoteCoreFile;    /* Malloced name of core file. */
  197. static int remoteOffset;    /* Offset used to convert addresses to 
  198.                  * offsets into core file. */
  199. StopInfo    remoteStopInfo;    /* Current Dbg_StopInfo from core file. */
  200. static Dbg_DumpBounds remoteBounds;  /* Dump bounds from core file. */
  201.  
  202. /*
  203.  * IN_CORE_FILE - Returns TRUE if address is in the corefile.
  204.  */
  205. #define    IN_CORE_FILE(addr) ((addr) >= (CORE_ADDR) remoteBounds.kernelCodeStart\
  206.       && ((addr) < (CORE_ADDR) remoteBounds.fileCacheStart + \
  207.                           remoteBounds.fileCacheSize))
  208.  
  209. /*
  210.  *----------------------------------------------------------------------
  211.  *
  212.  * remote_core_file_command --
  213.  *
  214.  *    kgdb.sun4 core_file command.
  215.  *
  216.  * Results:
  217.  *    None.
  218.  *
  219.  * Side effects:
  220.  *    None.
  221.  *
  222.  *----------------------------------------------------------------------
  223.  */
  224.  
  225. void
  226. remote_core_file_command (filename, from_tty)
  227.      char *filename;
  228.      int from_tty;
  229. {
  230.   /* Discard all vestiges of any previous core file
  231.      and mark data and stack spaces as empty.  */
  232.  
  233.   if (remoteCoreFile)
  234.     free (remoteCoreFile);
  235.   remoteCoreFile = 0;
  236.  
  237.   if (remoteCoreChan >= 0)
  238.     close (remoteCoreChan);
  239.   remoteCoreChan = -1;
  240.   if (filename == 0) {
  241.     printf ("Corefile cleared.\n");
  242.     return;
  243.   }
  244.  
  245.   filename = tilde_expand (filename);
  246.   make_cleanup (free, filename);
  247.  
  248.   remoteCoreChan = open (filename, O_RDONLY, 0);
  249.   if (remoteCoreChan < 0)
  250.     perror_with_name (filename);
  251.  
  252.   {
  253.     /*
  254.      * Read the StopInfo and bounds and start the debugging session.
  255.      */
  256.     int val;
  257.     val = myread (remoteCoreChan, &remoteStopInfo, sizeof remoteStopInfo);
  258.     if (val < 0)
  259.       perror_with_name (filename);
  260.     val = myread (remoteCoreChan, &remoteBounds, sizeof remoteBounds);
  261.     if (val < 0)
  262.       perror_with_name (filename);
  263.     remote_debugging = 1;
  264.     remoteOffset = remoteBounds.kernelCodeStart - sizeof(remoteStopInfo) -
  265.             sizeof(remoteBounds);
  266.     start_remote();
  267.   }
  268. }
  269.  
  270.  
  271. /* Open a connection to a remote debugger.
  272.    NAME is the filename used for communication.  */
  273.  
  274. void
  275. remote_open (name, from_tty)
  276.      char *name;
  277.      int from_tty;
  278. {
  279.   if (remoteCoreChan >= 0) {
  280.       error("Can't attach a machine when using a corefile\n");
  281.       return;
  282.   }
  283.  
  284.   hostName = savestring(name,strlen(name));
  285.   if (from_tty)
  286.     printf ("Remote debugging using %s\n", name);
  287.   push_target (&remote_ops);
  288.   remote_debugging = 1;
  289.   start_remote ();
  290. }
  291.  
  292. char *
  293. remote_version()
  294. {
  295.   static char    version[1024];
  296.   
  297.   ERROR_NO_ATTACHED_HOST;
  298.   Kdbx_Trace(DBG_GET_VERSION_STRING, 0, version, 1024);
  299.   return version;
  300. }
  301.  
  302.  
  303.  
  304. /* Tell the remote machine to resume.  */
  305.  
  306. int     step_addr, step_addr_contents[2];
  307.  
  308. void
  309. remote_resume (step, signal)
  310.      int step, signal;
  311. {
  312.   
  313.   if (signal)
  314.     error ("Can't send signals to a remote system.");
  315.   ERROR_NO_ATTACHED_HOST;
  316.   step_addr = -2;
  317.   if (step) {
  318.     if (Kdbx_Trace( DBG_SINGLESTEP, 0, 0, sizeof(int)) < 0) {
  319.       error("error trying to continue process\n");
  320.     }
  321.   } else {
  322.     if (Kdbx_Trace( DBG_CONTINUE, 0, 0, sizeof(int)) < 0) {
  323.       error("error trying to continue process\n");
  324.     }
  325.   }
  326.   
  327. }
  328.  
  329. /* Wait until the remote machine stops, then return,
  330.    storing status in STATUS just as `wait' would.  */
  331.  
  332. int
  333. remote_wait (status)
  334.      union wait *status;
  335. {
  336.   StopInfo    stopInfo;
  337.   int        cause;
  338.   int    text_size;
  339.   extern CORE_ADDR text_start, text_end;
  340. #if 0
  341.   if (remoteCoreChan >= 0) {
  342.     /*
  343.      * Debugging using core file, just set text_{start, end} and
  344.      * returned stopped signal.
  345.      */
  346.     status->w_status = 0;
  347.     status->w_stopval = WSTOPPED;
  348.     cause = remoteStopInfo.trapType;
  349.     status->w_stopsig = sig_mapping[cause].unixSignal;
  350.     if ((lastPid == -1) && !sig_mapping[cause].dbgSig) { 
  351.       printf("Kernel returns with signal (%d) %s\n", cause,
  352.          sig_mapping[trap].sig_name);
  353.     }
  354.     text_start = remoteBounds.kernelCodeStart;
  355.     text_end = remoteBounds.kernelCodeStart + remoteBounds.kernelCodeSize;
  356.     return status->w_stopsig;
  357.   }
  358. #endif
  359.   ERROR_NO_ATTACHED_HOST;
  360.   
  361.   if (Kdbx_Trace(DBG_GET_STOP_INFO, (char *) 0, (char *)&stopInfo,
  362.          sizeof(stopInfo)) != 0) {
  363.     error("Can't get stop info\n");
  364.   }
  365. #if 0
  366.   if (Kdbx_Trace(DBG_GET_DUMP_BOUNDS, (char *) 0, (char *)&remoteBounds,
  367.          sizeof(remoteBounds)) != 0) {
  368.     error("Can't get dump bounds\n");
  369.   }
  370. #endif
  371.   status->w_status = 0;
  372.   status->w_stopval = WSTOPPED;
  373.   cause = remoteStopInfo.trapType;
  374.   status->w_stopsig = sig_mapping[cause].unixSignal;
  375.   if ((lastPid != -1) && !sig_mapping[cause].dbgSig) { 
  376.     printf("Kernel returns with signal (%d) %s\n",stopInfo.trapType,
  377.        sig_mapping[cause].sig_name);
  378.   }
  379.  
  380.   text_start = stopInfo.codeStart;
  381. #if 0  
  382.   text_size = remoteBounds.kernelCodeSize;
  383. #else
  384.   text_size = 0xc0000000 - text_start;
  385. #endif
  386.   text_end = text_start+text_size;
  387.   return status->w_stopsig;
  388. }
  389.  
  390. /* Read the remote registers into the block REGS.  */
  391. #define FIRST_LOCAL_REGNUM    16
  392. void
  393. remote_fetch_registers (regno)
  394.      int regno;
  395. {
  396.   StopInfo    stopInfo;
  397.   char regs[REGISTER_BYTES];
  398.   int i;
  399. #if 0
  400.   if (remoteCoreChan >= 0) {
  401.     
  402.     bcopy(remoteStopInfo.regs.globals,regs,4*8);
  403.     bcopy(remoteStopInfo.regs.ins,regs+4*8,4*8);
  404.     ((int *)regs)[Y_REGNUM] = remoteStopInfo.regs.y; 
  405.     ((int *)regs)[PS_REGNUM] = remoteStopInfo.regs.curPsr; 
  406.     ((int *)regs)[PC_REGNUM] = remoteStopInfo.regs.pc; 
  407.     ((int *)regs)[NPC_REGNUM] = remoteStopInfo.regs.nextPc; 
  408.     remote_read_bytes(remoteStopInfo.regs.ins[6], 
  409.               ((int *) regs) + FIRST_LOCAL_REGNUM,4*16);
  410.     return;
  411.   }
  412. #endif
  413.   ERROR_NO_ATTACHED_HOST;
  414.   Kdbx_Trace(DBG_GET_STOP_INFO, (char *) 0, (char *)&stopInfo,
  415.          sizeof(stopInfo));
  416.   bcopy(stopInfo.regs.regs,regs,4*32);
  417.   bcopy(stopInfo.regs.fpRegs,regs+4*32,4*32);
  418.   ((int *)regs)[PC_REGNUM] = (int) stopInfo.regs.pc; 
  419.   ((int *)regs)[FP_REGNUM] = (int) stopInfo.regs.regs[29]; 
  420.   ((int *)regs)[SP_REGNUM] = (int) stopInfo.regs.regs[29]; 
  421.   ((int *)regs)[HI_REGNUM] = stopInfo.regs.mfhi; 
  422.   ((int *)regs)[LO_REGNUM] = stopInfo.regs.mflo; 
  423.   ((int *)regs)[FCRCS_REGNUM] = stopInfo.regs.fpStatusReg; 
  424.   for (i = 0; i < NUM_REGS; i++)
  425.     supply_register (i, ®s[REGISTER_BYTE(i)]);
  426. }
  427.  
  428.  
  429. int
  430. remote_attach(pid)
  431.      int    pid;
  432. {
  433.   int    status;
  434.   struct expression *expr;
  435.   register struct cleanup *old_chain;
  436.   register value val;
  437.   int    machRegStateAddr;
  438.   Proc_ControlBlock    *procPtr;
  439.   Mach_RegState machRegState;
  440.   char    exp[128];
  441.   
  442.   ERROR_NO_ATTACHED_HOST;
  443.   if (pid != lastPid) {
  444.     Kdbx_Trace(DBG_SET_PID, &pid, 0,sizeof(int));
  445.     lastPid = pid;
  446.   }
  447.   start_remote();
  448.   return 1;
  449. }
  450.  
  451. void
  452. remote_detach(args, from_tty)
  453.      char *args;
  454.      int from_tty;
  455. {
  456.   int cur_pc;
  457.   
  458.   ERROR_NO_ATTACHED_HOST;
  459.   cur_pc = read_pc();
  460.   if (args) 
  461.     Kdbx_Trace(DBG_DETACH, &cur_pc, 0, sizeof(int));
  462.   remote_clean_up();
  463.   pop_target ();
  464.   remote_debugging = 0;
  465.   if (from_tty)
  466.     printf("Ending remote debugging.\n");
  467. }
  468.  
  469.  
  470.  
  471. /* Read a word from remote address ADDR and return it.
  472.    This goes through the data cache.  */
  473.  
  474. int
  475. remote_fetch_word (addr)
  476.      CORE_ADDR addr;
  477. {
  478.   
  479.   int buffer;
  480.   extern CORE_ADDR text_start, text_end;
  481.   
  482.   ERROR_NO_ATTACHED_HOST;
  483.   if (addr >= text_start && addr < text_end)
  484.     {
  485.       if (Kdbx_Trace(DBG_INST_READ, addr, &buffer, sizeof(int)) != 0) {
  486.     errno = EIO;
  487.     return 0;
  488.       }
  489.       return buffer;
  490.     }
  491.   if (Kdbx_Trace(DBG_DATA_READ, addr, &buffer, sizeof(int)) != 0) {
  492.     errno = EIO;
  493.     return 0;
  494.   }
  495.   return buffer;
  496. }
  497.  
  498. /* Write a word WORD into remote address ADDR.
  499.    This goes through the data cache.  */
  500.  
  501. void
  502. remote_store_word (addr, word)
  503.      CORE_ADDR addr;
  504.      int word;
  505. {
  506.   extern CORE_ADDR text_start, text_end;
  507.   ERROR_NO_ATTACHED_HOST;
  508.   if (addr >= text_start && addr < text_end)
  509.     {
  510.       if (Kdbx_Trace(DBG_INST_WRITE, &word, addr, sizeof(word))!= 0) {
  511.     errno = EIO;
  512.       }
  513.       return;
  514.     }
  515.   if ( Kdbx_Trace(DBG_DATA_WRITE,  &word, addr, sizeof(word)) != 0) {
  516.     errno = EIO;
  517.   }
  518.   return;
  519. }
  520.  
  521. /* Write memory data directly to the remote machine.
  522.    This does not inform the data cache; the data cache uses this.
  523.    MEMADDR is the address in the remote memory space.
  524.    MYADDR is the address of the buffer in our space.
  525.    LEN is the number of bytes.  */
  526.  
  527. int
  528. remote_write_bytes (memaddr, myaddr, len)
  529.      CORE_ADDR memaddr;
  530.      char *myaddr;
  531.      int len;
  532. {
  533.   extern CORE_ADDR text_start, text_end;
  534.   ERROR_NO_ATTACHED_HOST;
  535.   if (memaddr >= text_start && memaddr < text_end)
  536.     {
  537.       return Kdbx_Trace(DBG_INST_WRITE, myaddr, memaddr, len);
  538.      }
  539.   return Kdbx_Trace(DBG_DATA_WRITE,  myaddr, memaddr, len);
  540. }
  541.  
  542. /* Read memory data directly from the remote machine.
  543.    This does not use the data cache; the data cache uses this.
  544.    MEMADDR is the address in the remote memory space.
  545.    MYADDR is the address of the buffer in our space.
  546.    LEN is the number of bytes.  */
  547.  
  548. int
  549. remote_read_bytes (memaddr, myaddr, len)
  550.      CORE_ADDR memaddr;
  551.      char *myaddr;
  552.      int len;
  553. {
  554.   int err;
  555.   ERROR_NO_ATTACHED_HOST;
  556.   return Kdbx_Trace(DBG_DATA_READ, memaddr, myaddr, len);
  557. }
  558.  
  559. #if 0
  560. /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
  561.    at debugger address MYADDR.  Returns errno value.  */
  562. int
  563. remote_read_inferior_memory(memaddr, myaddr, len)
  564.      CORE_ADDR memaddr;
  565.      char *myaddr;
  566.      int len;
  567. {
  568.   int xfersize, err;
  569.   while (len > 0)
  570.     {
  571.       if (len > MAXBUFBYTES)
  572.     xfersize = MAXBUFBYTES;
  573.       else
  574.     xfersize = len;
  575.       
  576.       err = remote_read_bytes (memaddr, myaddr, xfersize);
  577.       if (err != 0) 
  578.     return err;
  579.       memaddr += xfersize;
  580.       myaddr  += xfersize;
  581.       len     -= xfersize;
  582.     }
  583.   return 0; /* no error */
  584. }
  585.  
  586. /* Copy LEN bytes of data from debugger memory at MYADDR
  587.    to inferior's memory at MEMADDR.  Returns errno value.  */
  588. int
  589. remote_write_inferior_memory (memaddr, myaddr, len)
  590.      CORE_ADDR memaddr;
  591.      char *myaddr;
  592.      int len;
  593. {
  594.   int xfersize;
  595.   int err;
  596.   while (len > 0)
  597.     {
  598.       if (len > MAXBUFBYTES)
  599.     xfersize = MAXBUFBYTES;
  600.       else
  601.     xfersize = len;
  602.       
  603.       err = remote_write_bytes(memaddr, myaddr, xfersize);
  604.       if (err != 0) {
  605.     return err;
  606.       }
  607.       
  608.       memaddr += xfersize;
  609.       myaddr  += xfersize;
  610.       len     -= xfersize;
  611.     }
  612.   return 0; /* no error */
  613. }
  614. #endif /* 0 */
  615.  
  616. /* Prepare to store registers.  Since we send them all, we have to
  617.    read out the ones we don't want to change first.  */
  618.  
  619. void 
  620. remote_prepare_to_store ()
  621. {
  622.   remote_fetch_registers (-1);
  623. }
  624.  
  625. /* Store the remote registers from the contents of the block REGS.  */
  626.  
  627. void
  628. remote_store_registers (regs,regno)
  629.      char *regs;
  630.      int    regno;
  631. {
  632.   int    i;
  633.   
  634.   ERROR_NO_ATTACHED_HOST;
  635.   if (regno < 0) { 
  636.     for (i = 0; i < 32 + 32; i++) {
  637.       Kdbx_Trace(DBG_WRITE_REG, &(((int *)regs)[i]),
  638.          Regnum_to_index(i),sizeof(int));
  639.     }    
  640.     Kdbx_Trace(DBG_WRITE_REG, ((int *)regs)+PC_REGNUM,
  641.            Regnum_to_index(PC_REGNUM),sizeof(int));
  642.     Kdbx_Trace(DBG_WRITE_REG, ((int *)regs)+HI_REGNUM,
  643.            Regnum_to_index(HI_REGNUM),sizeof(int));
  644.     Kdbx_Trace(DBG_WRITE_REG, ((int *)regs)+LO_REGNUM,
  645.            Regnum_to_index(LO_REGNUM),sizeof(int));
  646.     Kdbx_Trace(DBG_WRITE_REG, ((int *)regs)+FCRCS_REGNUM,
  647.            Regnum_to_index(FCRCS_REGNUM),sizeof(int));
  648.   } else {
  649.     int    ind = Regnum_to_index(regno);
  650.     if (ind >= 0) 
  651.       Kdbx_Trace(DBG_WRITE_REG, ((int *)regs)+regno,ind,sizeof(int));
  652.     else
  653.       remote_write_bytes(((int *) regs)[SP_REGNUM], 
  654.              ((int *) regs) + regno,4);
  655.   }
  656. }
  657.  
  658. /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
  659.    to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
  660.    nonzero.  Returns length of data written or read; 0 for error.  */
  661.  
  662. /* ARGSUSED */
  663. int
  664. remote_xfer_memory(memaddr, myaddr, len, should_write, target)
  665.      CORE_ADDR memaddr;
  666.      char *myaddr;
  667.      int len;
  668.      int should_write;
  669.      struct target_ops *target;            /* ignored */
  670. {
  671.   int origlen = len;
  672.   int xfersize;
  673.   while (len > 0)
  674.     {
  675.       if (len > MAXBUFBYTES)
  676.     xfersize = MAXBUFBYTES;
  677.       else
  678.     xfersize = len;
  679.       
  680.       if (should_write)
  681.     remote_write_bytes(memaddr, myaddr, xfersize);
  682.       else
  683.     remote_read_bytes (memaddr, myaddr, xfersize);
  684.       memaddr += xfersize;
  685.       myaddr  += xfersize;
  686.       len     -= xfersize;
  687.     }
  688.   return origlen; /* no error possible */
  689. }
  690.  
  691. /* 
  692.  * Call a remote function.
  693.  */
  694. call_remote_function(funaddr,nargs,numBytes,argBuffer)
  695.      CORE_ADDR funaddr;
  696.      int        nargs;
  697.      int        numBytes;
  698.      char    *argBuffer;
  699. {
  700.   int    returnValue;
  701.   ERROR_NO_ATTACHED_HOST;
  702.   Kdbx_Trace(DBG_BEGIN_CALL, (char *)0, (char *)0, 0);  
  703.   returnValue = Kdbx_Trace(DBG_CALL_FUNCTION,argBuffer,funaddr,numBytes);
  704.   Kdbx_Trace(DBG_END_CALL, (char *)0, (char *)0, 0);       
  705.   return returnValue;
  706. }
  707.  
  708. void
  709. remote_close(quitting)
  710.      int quitting;
  711. {
  712. }
  713.  
  714. remote_clean_up()
  715. {
  716.   MARK_DISCONNECTED;
  717. }
  718.  
  719.  
  720. read_kmem(memaddr, myaddr, len)
  721.      char *memaddr;
  722.      char *myaddr;
  723.      int      len;
  724. {
  725.   static int fd = -1;
  726.   int count;
  727.   
  728.   if (fd < 0) { 
  729.     char template[100];
  730.     /*
  731.      * Open a temp file to write counters to. We unlink the file so it will
  732.      * disappear when we exit.
  733.      */
  734.     strcpy(template, "/tmp/kgdbXXXXXXXX");
  735.     fd = mkstemp(template);
  736.     if (fd < 0) {
  737.       error("open kmem tmp file");
  738.     }
  739.     (void) unlink(template);
  740.   }
  741.   if (lseek(fd, 0, L_SET) < 0) {
  742.     error("lseek kmem file");
  743.   }
  744.   count = write(fd, memaddr, len);
  745.   if (count != len) {
  746.     return EIO;
  747.   }
  748.   
  749.   /*
  750.    * Rewind the file and read the counters from it.
  751.    */
  752.   count = lseek(fd, 0, L_SET);
  753.   if (count >= 0) {
  754.     count = read(fd, myaddr, len);
  755.   }
  756.   if (count != len) {
  757.     return EIO;
  758.   }
  759.   return 0;
  760. }
  761.  
  762. void
  763. remote_reboot (args)
  764.      char *args;
  765. {
  766.   
  767.   ERROR_NO_ATTACHED_HOST;
  768.   if (!args)
  769.     args = "";
  770.   
  771.   Kdbx_Trace(DBG_REBOOT, args, NULL, strlen(args));
  772. }
  773.  
  774. void
  775. remote_files_info ()
  776. {
  777.   printf ("remote files info missing here.  FIXME.\n");
  778. }
  779.  
  780. struct target_ops remote_ops = {
  781.   "remote", "Remote serial target in gdb-specific protocol",
  782.   "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
  783.  Specify the serial device it is connected to (e.g. /dev/ttya).", 
  784.     remote_open, 
  785.     remote_close, 
  786.     remote_attach,
  787.     remote_detach, 
  788.     remote_resume, 
  789.     remote_wait, /* attach */ 
  790.     remote_fetch_registers, 
  791.     remote_store_registers, 
  792.     remote_prepare_to_store, 
  793.     0, 0, /* conv_from, conv_to */ 
  794.     remote_xfer_memory, 
  795.     remote_files_info, 
  796.     0, 0, /* insert and remove breakpoint */
  797.     0, 0, 0, 0, 0, /* Terminal crud */ 
  798.     remote_detach, /* kill */ 
  799.     0, /* load */ 
  800.     0, /* lookup_symbol */ 
  801.     0, 0, /* create_inferior FIXME, mourn_inferior FIXME */ 
  802.     process_stratum, 0, /* next */ 
  803.     1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */ 
  804.     0, 0, /* Section pointers */ 
  805.     OPS_MAGIC, /* Always the last thing */
  806.   };
  807.  
  808. void
  809. _initialize_remote ()
  810. {
  811.   add_target (&remote_ops);
  812. }
  813.  
  814. #include <sys/types.h>
  815. #include <sys/socket.h>
  816. #include <sys/time.h>
  817. #include <netinet/in.h>
  818. #include <netdb.h>
  819. #include <sgtty.h>
  820.  
  821. /*
  822.  * Direct mapped cache of data and code.   The cache is flushed after every
  823.  * step and continue by incrementing the version number.  Flushing code
  824.  * isn't necessary but since kdbx already has an internal code cache it
  825.  * doesn't hurt and makes life easier.
  826.  */
  827. static    int    cacheBlockSize = -1;
  828. static    int    cacheBlockShift = -1;
  829. static    int    cacheSize = 128 * 1024;
  830. #define    CACHE_BLOCK_MASK     (cacheSize / cacheBlockSize - 1)
  831. #define    CACHE_BLOCK_OFFSET_MASK    (cacheBlockSize - 1)
  832. #define    NUM_CACHE_BLOCKS    (cacheSize >> cacheBlockShift)
  833. #define    CACHE_OFFSET_MASK    (cacheSize - 1)
  834. #define    GET_CACHE_BLOCK(address) (((unsigned int) address) >> cacheBlockShift)
  835.  
  836. /*
  837.  * Stuff for the serial port.
  838.  */
  839. static    int    kernChannel = 0;
  840.  
  841.  
  842. /*
  843.  * Message buffers.
  844.  */
  845. static Dbg_Msg    msg;
  846. static int    msgSize;
  847. #define    REPLY_BUFFER_SIZE    16384
  848. static    char    replyBuffer[REPLY_BUFFER_SIZE];
  849. static    char    requestBuffer[DBG_MAX_REQUEST_SIZE];
  850. /*
  851.  * The starting message number is set to 0x40000000 so that the debugger
  852.  * stub can differentiate between messages from kgdb and kdbx.  Once
  853.  * kdbx is gone the msgNum can be initialized to 0.
  854.  */
  855. #ifdef KDBX
  856. #define FIRST_MSG 0x40000000
  857. static    int    msgNum = FIRST_MSG;
  858. #else
  859. static    int    msgNum = 0;
  860. #endif
  861.  
  862. static void    RecvReply();
  863.  
  864. static    struct sockaddr_in    remote;
  865. static    int            kdbxTimeout = 1;
  866. static    int            netSocket;
  867.  
  868.  
  869. /*
  870.  *----------------------------------------------------------------------
  871.  *
  872.  * CreateSocket --
  873.  *
  874.  *    Creates a UDP socket connected to the Sprite host's kernel 
  875.  *    debugger port.
  876.  *
  877.  * Results:
  878.  *    The stream ID of the socket.
  879.  *
  880.  * Side effects:
  881.  *    None.
  882.  *
  883.  *----------------------------------------------------------------------
  884.  */
  885. static int
  886. CreateSocket(spriteHostName)
  887.     char    *spriteHostName;
  888. {
  889.     int            socketID;
  890.     struct hostent     *hostPtr;
  891.  
  892.     hostPtr = gethostbyname(spriteHostName);
  893.     if (hostPtr == (struct hostent *) NULL) {
  894.     error("CreateSocket: unknown host %s\n", spriteHostName);
  895.     }
  896.     if (hostPtr->h_addrtype != AF_INET) {
  897.     error("CreateSocket: bad address type for host %s\n", 
  898.         spriteHostName);
  899.     }
  900.  
  901.     socketID = socket(AF_INET, SOCK_DGRAM, 0);
  902.     if (socketID < 0) {
  903.     perror_with_name("CreateSocket: socket");
  904.     }
  905.  
  906.     bzero((Address)&remote, sizeof(remote));
  907.     bcopy(hostPtr->h_addr, (Address)&remote.sin_addr, hostPtr->h_length);
  908.     remote.sin_port = htons(DBG_UDP_PORT);
  909.     remote.sin_family = AF_INET;
  910.  
  911.     if (connect(socketID, (struct sockaddr *) &remote, sizeof(remote)) < 0) {
  912.     perror_with_name("CreateSocket: connect");
  913.     }
  914.  
  915.     return(socketID);
  916. }
  917.  
  918.  
  919. /*
  920.  * ----------------------------------------------------------------------------
  921.  *
  922.  *  StartDebugger --
  923.  *
  924.  *     Start off a new conversation with the debugger.
  925.  *
  926.  * Results:
  927.  *     None.
  928.  *
  929.  * Side effects:
  930.  *     Setup r network socket.
  931.  * ----------------------------------------------------------------------------
  932.  */
  933. static void
  934. StartDebugger()
  935. {
  936.         char    *host = hostName;
  937.     hostName = (char *) 0;
  938.     netSocket = CreateSocket(host);
  939.     hostName = host;
  940. }
  941.  
  942.  
  943. /*
  944.  * ----------------------------------------------------------------------------
  945.  *
  946.  *  SendRequest --
  947.  *
  948.  *     Send a request message to the kernel.
  949.  *
  950.  * Results:
  951.  *     None.
  952.  *
  953.  * Side effects:
  954.  *     None.
  955.  * ----------------------------------------------------------------------------
  956.  */
  957. static void
  958. SendRequest(numBytes, newRequest)
  959.     int        numBytes;
  960.     Boolean    newRequest;
  961. {
  962.      {
  963.     Dbg_Opcode    opcode;
  964.  
  965.     msgSize = numBytes;
  966.     if (newRequest) {
  967.         msgNum++;
  968.     }
  969.     *(int *)requestBuffer = msgNum;
  970.     bcopy(&msg, requestBuffer + 4, numBytes);
  971.     if (write(netSocket, requestBuffer, numBytes + 4) < numBytes + 4) {
  972.       MARK_DISCONNECTED;
  973.       perror_with_name("SendRequest: Couldn't write to the kernel socket\n");
  974.       return;
  975.     }
  976.     if (newRequest) {
  977.       opcode = (Dbg_Opcode) msg.opcode;
  978.       if (opcode == DBG_DETACH || opcode == DBG_CONTINUE ||
  979.           opcode == DBG_SINGLESTEP || opcode == DBG_DIVERT_SYSLOG || 
  980.           opcode == DBG_BEGIN_CALL || 
  981.           opcode == DBG_WRITE_REG || opcode == DBG_SET_PID) {
  982.         int    dummy;
  983.         /*
  984.          * Wait for explicit acknowledgments of these packets.
  985.          */
  986.         RecvReply(opcode, 4, &dummy, NULL, 1);
  987.       }
  988.     }
  989.     }
  990. }
  991.  
  992.  
  993. /*
  994.  * ----------------------------------------------------------------------------
  995.  *
  996.  *  RecvReply --
  997.  *
  998.  *     Receive a reply from the kernel.
  999.  *
  1000.  * Results:
  1001.  *     None.
  1002.  *
  1003.  * Side effects:
  1004.  *     None.
  1005.  * ----------------------------------------------------------------------------
  1006.  */
  1007. static void
  1008. RecvReply(opcode, numBytes, destAddr, readStatusPtr, timeout)
  1009.     Dbg_Opcode    opcode;
  1010.     int        numBytes;
  1011.     char    *destAddr;
  1012.     int    *readStatusPtr;
  1013.     int    timeout;
  1014. {
  1015.     int        status;
  1016.     int     resendRequest = 0;
  1017.  
  1018.     if (numBytes + 8 > REPLY_BUFFER_SIZE) {
  1019.     fprintf(stderr,"numBytes <%d> > REPLY_BUFFER_SIZE <%d>\n",
  1020.             numBytes + 8, REPLY_BUFFER_SIZE);
  1021.     abort();
  1022.     }
  1023.      {
  1024.     int        readMask;
  1025.     struct    timeval    interval;
  1026.     int        bytesRead;
  1027.  
  1028.     interval.tv_sec = kdbxTimeout;
  1029.     interval.tv_usec = 0;
  1030.     do {
  1031.         if (timeout) {
  1032.         int    numTimeouts;
  1033.  
  1034.         numTimeouts = 0;
  1035.         /*
  1036.          * Loop timing out and sending packets until a new packet
  1037.          * has arrived.
  1038.          */
  1039.         do {
  1040.             if (!resendRequest) { 
  1041.             readMask = 1 << netSocket;
  1042.             status = select(32, &readMask, NULL, NULL, &interval);
  1043.             } else {
  1044.             status = 0;
  1045.             resendRequest = 0;
  1046.             }
  1047.             if (status == 1) {
  1048.             break;
  1049.             } else if (status == -1) {
  1050.                 MARK_DISCONNECTED;
  1051.             perror_with_name("RecvReply: Couldn't select on socket.\n");
  1052.             } else if (status == 0) {
  1053.             SendRequest(msgSize, 0);
  1054.             numTimeouts++;
  1055.             if (numTimeouts % 10 == 0) {
  1056.                 fprintf(stderr, 
  1057.                     "Timing out and resending to host %s\n",
  1058.                     hostName);
  1059.                 fflush(stderr);
  1060.                 QUIT;
  1061.             }
  1062.             }
  1063.         } while (1);
  1064.         }
  1065.         if (opcode == DBG_DATA_READ || opcode == DBG_INST_READ ||
  1066.         opcode == DBG_GET_VERSION_STRING) {
  1067.         /*
  1068.          * Data and instruction reads return variable size packets.
  1069.          * The first two ints are message number and status.  If
  1070.          * the status is OK then the data follows.
  1071.          */
  1072.         immediate_quit++;
  1073.         bytesRead = read(netSocket, replyBuffer, numBytes + 8);
  1074.         immediate_quit--;
  1075.         if (bytesRead < 0) {
  1076.             MARK_DISCONNECTED;
  1077.             perror_with_name("RecvReply: Error reading socket.");
  1078.         }
  1079.         /*
  1080.          * Check message number before the size because this could
  1081.          * be an old packet.
  1082.          */
  1083.         if (*(int *)replyBuffer != msgNum) {
  1084. #ifdef KDBX
  1085.             printf("RecvReply: Old message number = %d, expecting %d\n",
  1086.                 *(int *)replyBuffer - FIRST_MSG, 
  1087.                 msgNum - FIRST_MSG);
  1088. #else
  1089.             printf("RecvReply: Old message number = %d, expecting %d\n",
  1090.                 *(int *)replyBuffer, msgNum);
  1091. #endif
  1092.             fflush(stdout);
  1093.             resendRequest = 1;
  1094.             continue;
  1095.         }
  1096.         if (bytesRead == 8) {
  1097.             /*
  1098.              * Only 8 bytes so the read failed and there is no data.
  1099.              */
  1100.             *readStatusPtr = 0;
  1101.             return;
  1102.         }
  1103.             if (opcode == DBG_GET_VERSION_STRING) {
  1104.              strncpy(destAddr, (char *)(replyBuffer + 4),numBytes);
  1105.              return;
  1106.         }
  1107.         if (bytesRead != numBytes + 8) {
  1108.             printf("RecvReply: Short read (1): op=%d exp=%d read=%d",
  1109.                 opcode, numBytes + 4, bytesRead);
  1110.             continue;
  1111.         }
  1112.         *readStatusPtr = 1;
  1113.         bcopy(replyBuffer + 8, destAddr, numBytes);
  1114.         return;
  1115.         } else if (opcode == DBG_END_CALL) {
  1116.         int    length;
  1117.         /*
  1118.          * End call returns a variable size packet that contains
  1119.          * the result of the call. The format of the message is 
  1120.          * message number, length, data.
  1121.          */
  1122.         immediate_quit++;
  1123.         bytesRead = read(netSocket, replyBuffer, REPLY_BUFFER_SIZE);
  1124.         immediate_quit--;
  1125.         if (bytesRead < 0) {
  1126.             MARK_DISCONNECTED;
  1127.             perror_with_name("RecvReply: Error reading socket.");
  1128.         }
  1129.         /*
  1130.          * Check message number before the size because this could
  1131.          * be an old packet.
  1132.          */
  1133.         if (*(int *)replyBuffer != msgNum) {
  1134. #ifdef KDBX
  1135.             printf("RecvReply: Old message number = %d, expecting %d\n",
  1136.                 *(int *)replyBuffer - FIRST_MSG, 
  1137.                 msgNum - FIRST_MSG);
  1138. #else
  1139.             printf("RecvReply: Old message number = %d, expecting %d\n",
  1140.                 *(int *)replyBuffer, msgNum);
  1141. #endif
  1142.             fflush(stdout);
  1143.             resendRequest = 1;
  1144.             continue;
  1145.         }
  1146.         length = *( int *)(replyBuffer + 4);
  1147.         if (bytesRead - 8 != length) {
  1148.             fprintf(stderr, "RecvReply: Short read for syslog data\n");
  1149.             fprintf(stderr, "RecvReply: Read %d, length %d\n", 
  1150.             bytesRead - 8, length);
  1151.             fflush(stderr);
  1152.             length = bytesRead - 8;
  1153.         }
  1154.         if (length <= 0) {
  1155.             /*
  1156.              * No data.
  1157.              */
  1158.             *readStatusPtr = 0;
  1159.             return;
  1160.         }
  1161.         /*
  1162.          * Dump out the buffer.
  1163.          */
  1164.         write(1, replyBuffer + 8, length);
  1165.         *readStatusPtr = 1;
  1166.         return;
  1167.         } else {
  1168.         /*
  1169.          * Normal request so just read in the message which includes
  1170.          * the message number.
  1171.          */
  1172.         immediate_quit++;
  1173.         bytesRead = read(netSocket, replyBuffer, numBytes + 4);
  1174.         immediate_quit--;
  1175.         if (bytesRead < 0) {
  1176.             MARK_DISCONNECTED;
  1177.             perror_with_name("RecvReply: Error reading socket (2).");
  1178.         }
  1179.         /*
  1180.          * Check message number before size because it could be
  1181.          * an old packet.
  1182.          */
  1183.         if (*(int *)replyBuffer != msgNum) {
  1184. #ifdef KDBX
  1185.             printf("RecvReply: Old message number = %d, expecting %d\n",
  1186.                 *(int *)replyBuffer - FIRST_MSG, 
  1187.                 msgNum - FIRST_MSG);
  1188. #else
  1189.             printf("RecvReply: Old message number = %d, expecting %d\n",
  1190.                 *(int *)replyBuffer, msgNum);
  1191. #endif
  1192.             fflush(stdout);
  1193.             resendRequest = 1;
  1194.             continue;
  1195.         }
  1196.         if (bytesRead != numBytes + 4) {
  1197.             printf("RecvReply: Short read (2): op=%d exp=%d read=%d",
  1198.                 opcode, numBytes + 4, bytesRead);
  1199.         }
  1200.         if (*(int *)replyBuffer != msgNum) {
  1201.             continue;
  1202.         }
  1203.         bcopy(replyBuffer + 4, destAddr, numBytes);
  1204.         return;
  1205.         }
  1206.     } while (1);
  1207.     }
  1208. }
  1209.  
  1210.  
  1211. /*
  1212.  * ----------------------------------------------------------------------------
  1213.  *
  1214.  *  WaitForKernel --
  1215.  *
  1216.  *      Wait for the kernel to send us a message to indicate that it is waiting
  1217.  *    to be debugged.
  1218.  *
  1219.  * Results:
  1220.  *     None.
  1221.  *
  1222.  * Side effects:
  1223.  *     None.
  1224.  * ----------------------------------------------------------------------------
  1225.  */
  1226. static void
  1227. WaitForKernel()
  1228. {
  1229.     int    dummy;
  1230.  
  1231.     RecvReply(DBG_CONTINUE, 4, &dummy, NULL, 0);
  1232. }
  1233.  
  1234.  
  1235. /*
  1236.  * ----------------------------------------------------------------------------
  1237.  *
  1238.  * BlockInCache --
  1239.  *
  1240.  *     See if the given block at the given address is in the cache.
  1241.  *
  1242.  * Results:
  1243.  *     1 if found block in cache, 0 if didn't.
  1244.  *
  1245.  * Side effects:
  1246.  *     None.
  1247.  */
  1248. static int
  1249. BlockInCache(blockNum, addr)
  1250.     int        blockNum;
  1251.     char    *addr;
  1252. {
  1253.     blockNum = blockNum & CACHE_BLOCK_MASK;
  1254.     return((int) (cacheInfo[blockNum].version == currentVersion &&
  1255.        (unsigned int) cacheInfo[blockNum].realAddr == 
  1256.             ((unsigned int) (addr) & ~CACHE_BLOCK_OFFSET_MASK)));
  1257. }
  1258.  
  1259.  
  1260. /*
  1261.  * ----------------------------------------------------------------------------
  1262.  *
  1263.  * FetchBlock --
  1264.  *
  1265.  *     Fetch the given data block from the cache or the kernel if necessary.
  1266.  *
  1267.  * Results:
  1268.  *     1 if could fetch block into cache, 0 if couldn't.
  1269.  *
  1270.  * Side effects:
  1271.  *     Data cache modified.
  1272.  *
  1273.  * ----------------------------------------------------------------------------
  1274.  */
  1275. static int
  1276. FetchBlock(blockNum, srcAddr, opcode)
  1277.     int        blockNum;
  1278.     char    *srcAddr;
  1279.     Dbg_Opcode    opcode;
  1280. {
  1281.     int    successfulRead;
  1282.  
  1283.     blockNum = blockNum & CACHE_BLOCK_MASK;
  1284.     srcAddr = (char *) ((unsigned int) (srcAddr) & ~CACHE_BLOCK_OFFSET_MASK);
  1285.  
  1286.     if (BlockInCache(blockNum, srcAddr)) {
  1287.     return(1);
  1288.     }
  1289.     msg.opcode = opcode;
  1290.     msg.data.readMem.address = (int) srcAddr;
  1291.     msg.data.readMem.numBytes = cacheBlockSize;
  1292.     SendRequest(sizeof(msg.opcode) + sizeof(Dbg_ReadMem), 1);
  1293.     RecvReply(opcode, cacheBlockSize, 
  1294.         &dataCache[(unsigned int) (srcAddr) & CACHE_OFFSET_MASK],
  1295.         &successfulRead, 1);
  1296.     if (successfulRead) {
  1297.     cacheInfo[blockNum].version = currentVersion;
  1298.     cacheInfo[blockNum].realAddr = srcAddr;
  1299.     }
  1300.     return(successfulRead);
  1301. }
  1302.  
  1303.  
  1304.  
  1305. /*
  1306.  * ----------------------------------------------------------------------------
  1307.  *
  1308.  * Kdbx_Trace --
  1309.  *
  1310.  *     Write the trace command over to the kernel.  
  1311.  *
  1312.  * Results:
  1313.  *     None.
  1314.  *
  1315.  * Side effects:
  1316.  *     None.
  1317.  *
  1318.  * ----------------------------------------------------------------------------
  1319.  */
  1320. int 
  1321. Kdbx_Trace(opcode, srcAddr, destAddr, numBytes)
  1322.     Dbg_Opcode    opcode;        /* Which command */
  1323.     char    *srcAddr;    /* Where to read data from */
  1324.     char    *destAddr;    /* Where to write data to */
  1325.     int        numBytes;    /* The number of bytes to read or write */
  1326. {
  1327.     int            (*intrHandler)();
  1328.     int            i;
  1329.     int            retVal = 0;
  1330.     if (!initialized) {
  1331.     int    moreData;
  1332.     /*
  1333.      * Setup the cache and initiate a conversation with the other kernel.
  1334.      */
  1335.     if (cacheBlockSize == -1) {
  1336.          {
  1337.         cacheBlockSize = 256;
  1338.         cacheBlockShift = 8;
  1339.         }
  1340.     }
  1341.     dataCache = (char *) malloc(cacheSize);
  1342.     cacheInfo = (CacheInfo *) malloc(NUM_CACHE_BLOCKS * sizeof(CacheInfo));
  1343.     for (i = 0; i < NUM_CACHE_BLOCKS; i++) {
  1344.         cacheInfo[i].version = 0;
  1345.     }
  1346.     StartDebugger();
  1347.     /*
  1348.      * Dump the system log by faking a call command.
  1349.      */
  1350.     printf("Dumping system log ...\n");
  1351.     fflush(stdout);
  1352.     msg.opcode = (short)DBG_BEGIN_CALL;
  1353.     SendRequest(sizeof(msg.opcode), 1);
  1354.     msg.opcode = (short)DBG_END_CALL;
  1355.     do {
  1356.         SendRequest(sizeof(msg.opcode), 1);
  1357.         RecvReply(msg.opcode, 0, NULL, &moreData, 1);
  1358.     } while (moreData);
  1359.     initialized = 1;
  1360.     }
  1361.  
  1362.  
  1363.     if (opcode == DBG_DATA_READ || opcode == DBG_INST_READ) {
  1364.     int            firstBlock;
  1365.     int            lastBlock;
  1366.     unsigned    int    cacheOffset;
  1367.     int            toRead;
  1368.  
  1369.     /*
  1370.      * Read using the cache.
  1371.      */
  1372.     firstBlock = GET_CACHE_BLOCK(srcAddr); 
  1373.     lastBlock = GET_CACHE_BLOCK(srcAddr + numBytes - 1);
  1374.     for (i = firstBlock; i <= lastBlock; i++) {
  1375.         cacheOffset = ((unsigned int) srcAddr) & CACHE_OFFSET_MASK;
  1376.         if (i == lastBlock) {
  1377.         toRead = numBytes;
  1378.         } else if (i == firstBlock) {
  1379.         toRead = cacheBlockSize - 
  1380.                 (cacheOffset & CACHE_BLOCK_OFFSET_MASK);
  1381.         } else {
  1382.         toRead = cacheBlockSize;
  1383.         }
  1384.         if (!FetchBlock(i, srcAddr, opcode)) {
  1385.         return EIO;
  1386.         }
  1387.         bcopy(&dataCache[cacheOffset], destAddr, toRead);
  1388.         srcAddr += toRead;
  1389.         destAddr += toRead;
  1390.         numBytes -= toRead;
  1391.     }
  1392.     return(0);
  1393.     }
  1394.  
  1395.     if (opcode == DBG_DATA_WRITE || opcode == DBG_INST_WRITE) {
  1396.     int    firstBlock;
  1397.     int    lastBlock;
  1398.     int    cacheOffset;
  1399.     int    toWrite;
  1400.     char    *tSrcAddr;
  1401.     char    *tDestAddr;
  1402.     int    tNumBytes;
  1403.  
  1404.     /*
  1405.      * If the block that is being fetched is in the cache then write the
  1406.      * data there first before sending it over to the kernel.
  1407.      */
  1408.     tSrcAddr = srcAddr;
  1409.     tDestAddr = destAddr;
  1410.     tNumBytes = numBytes;
  1411.  
  1412.     firstBlock = GET_CACHE_BLOCK(destAddr); 
  1413.     lastBlock = GET_CACHE_BLOCK(destAddr + numBytes - 1);
  1414.     for (i = firstBlock; i <= lastBlock; i++) {
  1415.         cacheOffset = ((int) tDestAddr) & CACHE_OFFSET_MASK;
  1416.         if (i == lastBlock) {
  1417.         toWrite = tNumBytes;
  1418.         } else if (i == firstBlock) {
  1419.         toWrite = cacheBlockSize - 
  1420.                 (cacheOffset & CACHE_BLOCK_OFFSET_MASK);
  1421.         } else {
  1422.         toWrite = cacheBlockSize;
  1423.         }
  1424.         if (BlockInCache(i, tDestAddr)) {
  1425.         bcopy(tSrcAddr, &dataCache[cacheOffset], tNumBytes);
  1426.         }
  1427.         tSrcAddr += toWrite;
  1428.         tDestAddr += toWrite;
  1429.         tNumBytes -= toWrite;
  1430.     }
  1431.     }
  1432.  
  1433.     msg.opcode = (short) opcode;
  1434.  
  1435.     /*
  1436.      * Do the rest of the work for the desired operation.
  1437.      */
  1438.  
  1439.     switch (opcode) {
  1440.  
  1441.     /*
  1442.      * For these operations the desired data is read from the other
  1443.      * kernel and stored at destAddr.
  1444.      */
  1445.     case DBG_READ_ALL_REGS:
  1446.     case DBG_GET_STOP_INFO:
  1447.         SendRequest(sizeof(msg.opcode), 1);
  1448.         RecvReply(opcode, numBytes, destAddr, NULL, 1);
  1449.         break;
  1450.  
  1451.     /*
  1452.      * For this operation the desired data is read from srcAddr
  1453.      * and written to the other kernel.
  1454.      */
  1455.     case DBG_SET_PID:
  1456.         msg.data.pid = *(int *)srcAddr;
  1457.         SendRequest(sizeof(msg.opcode) + sizeof(msg.data.pid), 1);
  1458.         break;
  1459.  
  1460.     /*
  1461.      * When writing a general purpose register first the address to write
  1462.      * that is stored in destAddr must be given to the other kernel.
  1463.      * Then the data itself which is stored at srcAddr can be written over.
  1464.      */
  1465.     case DBG_WRITE_REG:
  1466.         msg.data.writeReg.regNum = (int) destAddr;
  1467.         msg.data.writeReg.regVal = *(int *) srcAddr;
  1468.         SendRequest(sizeof(msg.opcode) + sizeof(Dbg_WriteReg), 1);
  1469.         break;
  1470.  
  1471.     /*
  1472.      * When writing to the kernels instruction or data space first the
  1473.      * address of where to write to (destAddr) and then the number of
  1474.      * bytes to write (numBytes) must be sent over.  Finally all of
  1475.      * the data is read from srcAddr and written over.
  1476.      */
  1477.  
  1478.     case DBG_INST_WRITE:
  1479.     case DBG_DATA_WRITE: {
  1480.         char    writeStatus;
  1481.  
  1482.         msg.data.writeMem.address = (int) destAddr;
  1483.         msg.data.writeMem.numBytes = numBytes;
  1484.         bcopy(srcAddr, msg.data.writeMem.buffer, numBytes);
  1485.         SendRequest(sizeof(msg.opcode) + 2 * sizeof(int) + numBytes, 1);
  1486.         RecvReply(opcode, 1, &writeStatus, NULL, 1);
  1487.         if (writeStatus == 0) {
  1488.         retVal = EIO;
  1489.         fprintf(stderr, "ERROR: invalid write address 0x%x\n",destAddr);
  1490.         } 
  1491.         break;
  1492.     }
  1493.     case DBG_DIVERT_SYSLOG:
  1494.         msg.data.syslogCmd = (Dbg_SyslogCmd)srcAddr;
  1495.         SendRequest(sizeof(msg.opcode) + sizeof(Dbg_SyslogCmd), 1);
  1496.         break;
  1497.     case DBG_BEGIN_CALL:
  1498.         SendRequest(sizeof(msg.opcode), 1);
  1499.         break;
  1500.     case DBG_END_CALL: {
  1501.         Boolean    moreData;
  1502.         do {
  1503.         SendRequest(sizeof(msg.opcode), 1);
  1504.         RecvReply(opcode, 0, NULL, &moreData, 1);
  1505.         } while (moreData);
  1506.         break;
  1507.     }
  1508.  
  1509.     case DBG_DETACH: {
  1510.         msg.opcode = (short) DBG_DIVERT_SYSLOG;
  1511.         msg.data.syslogCmd = DBG_SYSLOG_TO_ORIG;
  1512.         SendRequest(sizeof(msg.opcode) + sizeof(Dbg_SyslogCmd), 1);
  1513.  
  1514.         msg.opcode = (short) DBG_DETACH;
  1515.         msg.data.pc = *(int *) srcAddr;
  1516.         SendRequest(sizeof(msg.opcode) + sizeof(msg.data.pc), 1);
  1517.         break;
  1518.     }
  1519.  
  1520.     case DBG_CONTINUE:
  1521.     case DBG_SINGLESTEP:
  1522.         SendRequest(sizeof(msg.opcode) + sizeof(msg.data.pc), 1);
  1523.         currentVersion++;
  1524.         WaitForKernel();
  1525.         break;
  1526.  
  1527.     case DBG_CALL_FUNCTION: {
  1528.         int        returnValue;
  1529.  
  1530.         msg.data.callFunc.address = (int) destAddr;
  1531.         msg.data.callFunc.numBytes = numBytes;
  1532.         bcopy(srcAddr, msg.data.callFunc.buffer, numBytes);
  1533.         SendRequest(sizeof(msg.opcode) + 2 * sizeof(int) + numBytes, 1);
  1534.         RecvReply(opcode, sizeof(returnValue), &returnValue, NULL, 1);
  1535.         return (returnValue);
  1536.     }
  1537.     case DBG_REBOOT: {
  1538.         msg.data.reboot.stringLength = numBytes;
  1539.         bcopy(srcAddr, msg.data.reboot.string, numBytes);
  1540.         SendRequest(sizeof(msg.opcode) + sizeof(int) + numBytes, 1);
  1541.         return (0);
  1542.     }
  1543.     case DBG_GET_VERSION_STRING: {
  1544.         SendRequest(sizeof(msg.opcode), 1);
  1545.         RecvReply(opcode,numBytes , destAddr, NULL, 1);
  1546.         return (0);
  1547.     }
  1548.     default:
  1549.         printf("Unknown opcode %d\n", opcode);
  1550.         return(-1);
  1551.     }
  1552.     return(retVal);
  1553. }
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563. @
  1564.  
  1565.  
  1566. 1.1
  1567. log
  1568. @Initial revision
  1569. @
  1570. text
  1571. @d333 6
  1572. d347 1
  1573. a347 2
  1574.   
  1575.   text_size = text_end - text_start;
  1576. d349 5
  1577. d764 1
  1578. a764 1
  1579.     0, 0, /* insert_breakpoint, remove_breakpoint, */ 
  1580. @
  1581.  
  1582.  
  1583. 1.1.1.1
  1584. log
  1585. @serial line support (doesn't work correctly)
  1586. @
  1587. text
  1588. @a31 1
  1589. #include <kernel/dbg.h>
  1590. a32 4
  1591. #ifndef DBG_ACK_SIZE
  1592. #define DBG_ACK_SIZE 1
  1593. #endif
  1594.  
  1595. d67 1
  1596. a67 1
  1597.     if (!hostName && !serialPort) error("No machine attached.");
  1598. a123 4
  1599. static int    serialDebug = 0;
  1600. static int    kernChannel = 0;
  1601. static char    *serialPort = NULL;
  1602.  
  1603. d251 4
  1604. a254 11
  1605.   if (*name == '/') {
  1606.       serialDebug = 1;
  1607.       serialPort = savestring(name,strlen(name));
  1608.       if (from_tty) {
  1609.       printf("Remote debugging using serial device %s\n", name);
  1610.       }
  1611.   } else {
  1612.       hostName = savestring(name,strlen(name));
  1613.       if (from_tty)
  1614.     printf ("Remote debugging using %s\n", name);
  1615.   }
  1616. d794 5
  1617. a893 48
  1618.     if (serialDebug) {
  1619.     struct         sgttyb     modes;
  1620.     int        i;
  1621.     char        buffer[32];
  1622.  
  1623.     kernChannel = open(serialPort, 2);
  1624.     if (kernChannel < 0) {
  1625.         perror_with_name("Could not open serial line\n");
  1626.         exit(1);
  1627.     }
  1628.  
  1629.     /*
  1630.      * Flush the line.
  1631.      */
  1632.     i = 0;
  1633.     ioctl(kernChannel, TIOCFLUSH, &i);
  1634.  
  1635.     /*
  1636.      * Turn off parity and echoing.
  1637.      */
  1638.     if (ioctl(kernChannel,TIOCGETP,&modes) < 0) {
  1639.         perror("ioctl get modes");
  1640.         abort();
  1641.     }
  1642.     printf("ispeed = %d, ospeed = %d\n", modes.sg_ispeed, modes.sg_ospeed);
  1643.     modes.sg_flags |= RAW|ANYP;
  1644.     modes.sg_flags &= ~ECHO;
  1645.     if (ioctl(kernChannel,TIOCSETP,&modes) < 0) {
  1646.         perror("ioctl put modes");
  1647.         abort();
  1648.     }
  1649.  
  1650.     /*
  1651.      * Send the other half a magic sequence of characters that it is
  1652.      * waiting for, and wait for the response. 
  1653.      */
  1654.     WriteSerial("Hey", 3, 1);
  1655.     sleep(5);
  1656.     ReadSerial(buffer, 5);
  1657.     buffer[5] = '\0';
  1658.     if (strcmp(buffer, "Aloha")) {
  1659.         printf("Remote gave wrong secret password: \"%s\"\n", buffer);
  1660.         close(kernChannel);
  1661.     } else {
  1662.         printf("Got the secret password\n");
  1663.     }
  1664.     } else {
  1665.  
  1666. a897 1
  1667.     }
  1668. d920 1
  1669. a920 24
  1670.     if (serialDebug) {
  1671.     /*
  1672.      * First send the opcode.
  1673.      */
  1674.     printf("Sending opcode\n");
  1675.     WriteSerial(&msg.opcode, sizeof(msg.opcode), 1);
  1676.     if ((Dbg_Opcode) msg.opcode != DBG_DATA_WRITE && 
  1677.         (Dbg_Opcode) msg.opcode != DBG_INST_WRITE) {
  1678.         /*
  1679.          * If not a write send the rest.
  1680.          */
  1681.         printf("Sending rest of command\n");
  1682.         WriteSerial(&msg.data, numBytes - sizeof(msg.opcode), 1);
  1683.     } else {
  1684.         /*
  1685.          * Send the size and numBytes first and then the data.
  1686.          */
  1687.         printf("Sending addr and numBytes\n");
  1688.         WriteSerial(&msg.data.writeMem, 2 * sizeof(int), 1);
  1689.         printf("Sending data\n");
  1690.         WriteSerial(msg.data.writeMem.buffer,
  1691.                    msg.data.writeMem.numBytes, 1);
  1692.     }
  1693.     } else {
  1694. a975 1
  1695.  
  1696. d981 1
  1697. a981 31
  1698.     if (serialDebug) {
  1699.     if (opcode == DBG_DATA_READ || opcode == DBG_INST_READ) {
  1700.         ReadSerial(&status, sizeof(status));
  1701.         if (status == 0) {
  1702.         *readStatusPtr = 0;
  1703.         return;
  1704.         }
  1705.         *readStatusPtr = 1;
  1706.         ReadSerial(destAddr, numBytes);
  1707.     } else if (opcode == DBG_END_CALL) {
  1708.         int        length;
  1709.         /*
  1710.          * End call returns the length and then the data.  First read
  1711.          * then length, then the data, then dump the log.
  1712.          */
  1713.         ReadSerial(&length, sizeof(length));
  1714.         printf("Remote says to read %d bytes\n", length);
  1715.         if (length > 1024) {
  1716.         abort();
  1717.         }
  1718.         if (length == 0) {
  1719.         *readStatusPtr = 0;
  1720.         } else {
  1721.         ReadSerial(replyBuffer, length);
  1722.         write(1, replyBuffer, length);
  1723.         *readStatusPtr = 1;
  1724.         }
  1725.     } else {
  1726.         ReadSerial(destAddr, numBytes);
  1727.     }
  1728.     } else {
  1729. a1186 8
  1730.     if (serialDebug) {
  1731.     unsigned char ch;
  1732.  
  1733.     if (read(kernChannel, &ch, 1) != 1) {
  1734.         fprintf(stderr,"Read from kernChannel (2)");
  1735.         abort();
  1736.     }
  1737.     } else {
  1738. a1189 1
  1739.     }
  1740. a1260 142
  1741.  
  1742. /*
  1743.  * ----------------------------------------------------------------------------
  1744.  *
  1745.  * ReadSerial --
  1746.  *
  1747.  *     Read the given number of bytes over from the kernel on the serial line. 
  1748.  *
  1749.  * Results:
  1750.  *     None.
  1751.  *
  1752.  * Side effects:
  1753.  *     None.
  1754.  *
  1755.  * ----------------------------------------------------------------------------
  1756.  */
  1757. static int
  1758. ReadSerial(buf, numBytes)
  1759.     char *buf;        /* Buffer to read into */
  1760.     int  numBytes;    /* Number of bytes to read */
  1761. {
  1762.     int readSoFar;    /* The total number of bytes that we have read */
  1763.     int bytesRead;    /* The number of bytes read in the last read */
  1764.     int ackCount;    /* The number of bytes that have been acknowledgment */
  1765.  
  1766.     ackCount = 0;
  1767.     readSoFar = 0;
  1768.     printf("ReadSerial: reading %d bytes\n", numBytes);
  1769.     while (readSoFar < numBytes) {
  1770.     bytesRead = read(kernChannel, &buf[readSoFar], numBytes - readSoFar);
  1771.     if (bytesRead < 0) {
  1772.         MARK_DISCONNECTED;
  1773.         perror_with_name("ReadBytes: Couldn't read from the kernel channel\n");
  1774.         return(-1);
  1775.     }
  1776.  
  1777.     readSoFar += bytesRead;
  1778.     if (readSoFar - ackCount == DBG_ACK_SIZE) {
  1779.         printf("Acking\n");
  1780.         if (write(kernChannel, &readSoFar, 1) < 1) {
  1781.         MARK_DISCONNECTED;
  1782.         perror_with_name("ReadBytes: Couldn't write to kernel channel\n");
  1783.         return(-1);
  1784.         }
  1785.         printf("Ack done\n");
  1786.         ackCount += DBG_ACK_SIZE;
  1787.     }
  1788.     }
  1789.  
  1790.     return(0);
  1791. }
  1792.  
  1793. /*
  1794.  * ----------------------------------------------------------------------------
  1795.  *
  1796.  * WriteSerial --
  1797.  *
  1798.  *     Write the bytes over to the kernel across the serial line.  Every
  1799.  *     DBG_ACK_SIZE character that we write is acknowledged by a character
  1800.  *     that is sent by the other kernel.  This is so we don't get ahead
  1801.  *     of the other kernel.
  1802.  *
  1803.  * Results:
  1804.  *     None.
  1805.  *
  1806.  * Side effects:
  1807.  *     None.
  1808.  *
  1809.  * ----------------------------------------------------------------------------
  1810.  */
  1811. static int
  1812. WriteSerial(buf, numBytes, ack)
  1813.     char *buf;        /* Pointer to buffer to write */
  1814.     int  numBytes;    /* Number of bytes to write */
  1815.     Boolean    ack;    /* Acknowledge when done and every 3 characters. */
  1816. {
  1817.     unsigned char input;
  1818.     int    i;
  1819.     int    toWrite;
  1820.     int    j;
  1821.     int    delay = 4000000;
  1822.  
  1823.     if (numBytes == 0) {
  1824.     return(0);
  1825.     }
  1826.     printf("WriteSerial: writing %d bytes, ack = %d\n", numBytes, DBG_ACK_SIZE);
  1827.     if (!ack) {
  1828. #ifdef NOTDEF
  1829.     for (i = 0; i < numBytes; i++) {
  1830.         if (write(kernChannel, &buf[i], 1) < 1) {
  1831.         MARK_DISCONNECTED;
  1832.         perror_with_name(
  1833.             "WriteBytes: Couldn't write to the kernel channel\n");
  1834.         return(-1);
  1835.         }
  1836.         for (j = 0; j < delay; j++);
  1837.     }
  1838. #endif  /* NOTDEF */
  1839.  
  1840.     if (write(kernChannel, buf, numBytes) < numBytes) {
  1841.         MARK_DISCONNECTED;
  1842.         perror_with_name("WriteBytes: Couldn't write to the kernel channel\n");
  1843.         return(-1);
  1844.     }
  1845.     return(0);
  1846.     }
  1847.  
  1848.     do {
  1849.     if (numBytes > DBG_ACK_SIZE) {
  1850.         toWrite = DBG_ACK_SIZE;
  1851.     } else {
  1852.         toWrite = numBytes;
  1853.     }
  1854. #ifdef NOTDEF
  1855.     for (i = 0; i < toWrite; i++) {
  1856.         if (write(kernChannel, &buf[i], 1) < 1) {
  1857.         MARK_DISCONNECTED;
  1858.         perror_with_name(
  1859.             "WriteBytes: Couldn't write to the kernel channel\n");
  1860.         return(-1);
  1861.         }
  1862.         for (j = 0; j < delay; j++);
  1863.     }
  1864. #endif  /* NOTDEF */
  1865.  
  1866.     printf("Writing %d bytes to channel\n", toWrite);
  1867.     if (write(kernChannel, buf, toWrite) < toWrite) {
  1868.         MARK_DISCONNECTED;
  1869.         perror_with_name("WriteBytes: Couldn't write to the kernel channel\n");
  1870.         return(-1);
  1871.     }
  1872.     buf += toWrite;
  1873.     numBytes -= toWrite;
  1874.  
  1875.     printf("Waiting for ack\n");
  1876.     if (read(kernChannel, &input, 1) < 1) {
  1877.         MARK_DISCONNECTED;
  1878.         perror_with_name("WriteBytes: Couldn't read from the kernel channel\n");
  1879.         return(-1);
  1880.     }
  1881.     printf("Got ack\n");
  1882.     } while (numBytes > 0);
  1883. a1261 3
  1884.     return(0);
  1885. }
  1886.  
  1887. d1294 1
  1888. a1294 4
  1889.         if (serialDebug) {
  1890.         cacheBlockSize = 32;
  1891.         cacheBlockShift = 5;
  1892.         } else {
  1893. @
  1894.